<?php
/**
 * Created by PhpStorm.
 * User: Mysic
 * Date: 2020/12/29
 * Time: 10:55
 */

namespace app\common\mysic\profitShare\procedures;

use app\common\model\divide\Service;
use app\common\model\divide\Store;
use app\common\model\divide\System;
use app\common\model\Order;
use app\common\model\Wxapp;
use app\common\mysic\MysicBase;
use think\Db;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\exception\DbException;

class ProfitOrder extends MysicBase
{
    /**
     * @param  Order  $userOrderEntity
     * @param  array  $agentList
     * @param  int $periodsNum
     * @param  array $systemSetting
     * @param Wxapp $wxAppEntity
     * @return false|int
     * @throws Exception
     */
    public function createSystemServiceProfitOrders(Order $userOrderEntity,array $agentList, int $periodsNum, array $systemSetting, Wxapp $wxAppEntity)
    {
        if(empty($agentList)) {
            throw new Exception('待分账的代理账号为空');
        }
        $insertData = $log = [];
        $agentRate = [];
        foreach($agentList as $key => $agent) {
            $data = [
                'name' => $agent['company_name'] ?? $agent['real_name'],
                'agent_id' => $agent['agent_id'],
                'amount' =>  bcmul(
                    bcdiv(strval($agent['service_charge']),'100',2),
                    bcdiv($userOrderEntity->pay_price, '100', 4),
                    4
                ),

                'abonus' => bcmul(strval($userOrderEntity->pay_price),'0.01',2),
                'order_no' => $userOrderEntity->order_no,
                'payment' => $userOrderEntity->pay_price,
                'transaction_id' => $userOrderEntity->transaction_id,
                'wxapp_id' => $userOrderEntity->wxapp_id,
                'status' => 0,
                'create_time' => time(),
                'periods_num' => $periodsNum
            ];

            $agent['type'] == 0 && $data['type'] = 1;
            $agent['type'] == 1 && $data['type'] = 2;
            $agent['type'] == 2 && $data['type'] = 3;
            $agentRate[] = $agent['service_charge'];
            $insertData[] = $data;
            $log[] = [
                'name' => $data['name'],
                'agent_id' => $data['agent_id'],
                'order_no' => $data['order_no'],
                'bonus' => $data['abonus']
            ];
        }
        switch(count($insertData)){
            case 1:
                $insertData[0]['amount'] = bcmul(
                    bcdiv(strval($agentRate[0]),'100',2),
                    bcdiv($userOrderEntity->pay_price, '100', 4),
                    4
                );
                $agentsProfitAmount = $insertData[0]['amount'];
                break;
            case 2:
                $insertData[0]['amount'] = bcmul(
                    bcdiv(strval($agentRate[0] - $agentRate[1]),'100',2),
                    bcdiv($userOrderEntity->pay_price, '100', 4),
                    4
                );
                $insertData[1]['amount'] = bcmul(
                    bcdiv(strval($agentRate[1]),'100',2),
                    bcdiv($userOrderEntity->pay_price, '100', 4),
                    4
                );
                $agentsProfitAmount = bcadd($insertData[0]['amount'], $insertData[1]['amount'], 4);
                break;
            case 3:
                $insertData[0]['amount'] = bcmul(
                    bcdiv(strval($agentRate[0] - $agentRate[1]),'100',2),
                    bcdiv($userOrderEntity->pay_price, '100', 4),
                    4
                );
                $insertData[1]['amount'] = bcmul(
                    bcdiv(strval($agentRate[1] - $agentRate[2]),'100',2),
                    bcdiv($userOrderEntity->pay_price, '100', 4),
                    4
                );
                $insertData[2]['amount'] = bcmul(
                    bcdiv(strval($agentRate[2]),'100',2),
                    bcdiv($userOrderEntity->pay_price, '100', 4),
                    4
                );
                $agentsProfitAmount = bcadd(bcadd($insertData[0]['amount'], $insertData[1]['amount'], 4), $insertData[2]['amount'], 4);
                break;
            default:
                $agentsProfitAmount = 0;
        }
        $model = new Service();
        $ret = $model->insertAll($insertData);
        if(!$ret) {
            throw new Exception('创建服务商分账流水单失败');
        }
        $model = new System();
        $systemConfig = $systemSetting;
        $systemRate = bcdiv(strval($wxAppEntity->system_rate), '100', 2);
        $model->account = $systemConfig[ 'mch_id' ];
        $model->order_no = $userOrderEntity->order_no;
        $model->wxapp_id       = $userOrderEntity->wxapp_id;//微信小程序内部编号
        $model->abonus         = bcmul(strval($userOrderEntity->pay_price), $systemRate, 2);//分账可得金额(单位/分)
        $model->amount         = bcsub( $model->abonus, $agentsProfitAmount, 4);//分红金额(单位/分)
        $model->description    = '分账给系统服务商';
        $model->payment        = $userOrderEntity->pay_price;//实际支付总金额(单位/分)
        $model->transaction_id = $userOrderEntity->transaction_id;//微信内部订单
        $model->status         = 0;//结算状态 0待分账 1已分账 2分账失败
        $model->create_time    = time();//写入时间
        $model->periods_num    = $periodsNum;//期号
        $model->isUpdate(false);
        $ret = $model->save();
        $systemProfitOrderEntity = $model->where('order_no', $userOrderEntity->order_no)->find();
        $serviceProfitOrderEntities = $model->where('order_no', $userOrderEntity->order_no)->select();
        $serviceProfitOrderEntities = $serviceProfitOrderEntities->all();
        RuntimeVariables::setSystemProfitOrderEntity($systemProfitOrderEntity);
        RuntimeVariables::setServiceProfitOrderEntities($serviceProfitOrderEntities);
        return $ret;
    }

    public function createStoreProfitOrder(Wxapp $wxAppEntity, Order $userOrderEntity, $profitAmount, $periodsNum)
    {
        $model = new Store();
        $model->account = $wxAppEntity->mchid;
        $model->order_no = $userOrderEntity->order_no;
        $model->wxapp_id = $userOrderEntity->wxapp_id;
        $model->agent_id = $wxAppEntity->agent_id;
        $model->payment = $userOrderEntity->pay_price;
        $model->transaction_id = $userOrderEntity->transaction_id;
        $model->status = 0;
        $model->create_time = time();
        $model->periods_num = $periodsNum;
        $model->amount = bcsub(strval($userOrderEntity->pay_price), bcadd(bcmul(strval($userOrderEntity->pay_price),'0.01', 2),  $profitAmount, 2), 2);
        $model->isUpdate(false);
        $ret = $model->save();
        $storeProfitOrderEntity = $model->where('order_no', $userOrderEntity->order_no)->find();
        RuntimeVariables::setStoreProfitOrderEntity($storeProfitOrderEntity);
        return $ret;
    }

    public function returnExceptBalanceToStore($orderNo, $exceptBalance)
    {
        $model = new Store();
        $this->log->info(['订单号' => $orderNo, '差额' => $exceptBalance], '分红差额返还商户参数');
        try {
            $storeProfitOrderEntity = $model->where('order_no', $orderNo)->find();
            return $storeProfitOrderEntity->save(['amount' => Db::raw('amount-' .$exceptBalance)]);
        } catch (DataNotFoundException|ModelNotFoundException|DbException $e) {
            $this->log->info(exceptionLogFormat($e), '分红差额返还商户时抛出异常');
            return false;
        }
    }
    //更新平台分账流水单状态
    public function updateSystemProfitOrder($entity, $status = 1, $msg = '分账成功'): bool
    {
        $data = [
            'status' => $status,
            'update_time' => time(),
            'fail_reason' => $msg
        ];
        return $entity->isUpdate(true)->save($data);
    }
    //更新服务商分账流水单状态
    public function updateServiceProfitOrder($entities, $status = 1, $msg = '分账成功'): bool
    {
        $model = new Service();
        $updateTime = \time();
        $updateList = [];
        foreach($entities as $entity) {
            $updateList[] = [
                'id' => $entity->id,
                'status' => $status,
                'fail_reason' => $msg,
                'update_time' => $updateTime
            ];
        }
        if(empty($updateList)) {
            return true;
        }
        try {
            $model->isUpdate()->saveAll($updateList);
        } catch (\Exception $e) {
            $this->log->error(exceptionLogFormat($e), '更新服务商分账流水单时抛出异常');
            return false;
        }
        return true;
    }
    //更新商户分账流水单状态
    public function updateStoreProfitOrder($entity, $status = 1, $msg = '分账成功'): bool
    {
        $data = [
            'status' => $status,
            'update_time' => time(),
            'fail_reason' => $msg
        ];
        return $entity->isUpdate(true)->save($data);
    }
}